#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <time.h>
#include "whm.h"
#include "md5.h"
#include "tinydir.h"
using namespace std;


//use *unix shell
int list_vh_cmd(WHM_CONTEXT *context)
{
	char md5[4096]; 
	  FILE *pp;
	  char shell[512];
	const char *kangle_home = context->getEnv(context->ctx,"kangle_home");	  
	sprintf(shell, "%s/etc/vh.d/*.xml", kangle_home);
	  pp = popen(shell, "r");
	  if (pp != NULL) {
	      fgets(md5, sizeof md5, pp);
	    }
	    pclose(pp);
	context->setValue(context->ctx,"list_vh", md5);
	return WHM_OK;
}

int list_vh(WHM_CONTEXT *context)
{
	char md5[40]; 
	tinydir_dir dir;
	char path[512];
	char localfile[512];
	std::stringstream s;
	char txt[1024] = "";
	int i;
	char total_vh_s[25];
	int total_vh;
	const char *kangle_home = context->getEnv(context->ctx,"kangle_home");

	snprintf(path,512, "%s/etc/vh.d/", kangle_home);
	if (tinydir_open_sorted(&dir, path) == -1)
	{
		perror("Error opening file");
		goto bail;
	}
	total_vh = 0;
	for (i = 0; i < dir.n_files; i++)
	{
		tinydir_file file;
		if (tinydir_readfile_n(&dir, &file, i) == -1)
		{
			perror("Error getting file");
			goto bail;
		}

		if (file.is_dir)
		{
			//printf("/");
		}else{
			total_vh++;
			sprintf(localfile, "%s%s", path,file.name);
			KMD5_file(localfile, md5);
			//sprintf(txt, "%s%s\t%s\t%d\n",txt, localfile, md5, mktime(localtime(&(file._s.st_mtime))));
			s << file.name << "\t" << md5 << "\t" << mktime(localtime(&(file._s.st_mtime))) << "\n"; //c++ style
			//printf("%s,%d", ctime(&(file._s.st_mtime)), mktime(localtime(&(file._s.st_mtime)))); //c style
		}
	}
	snprintf(total_vh_s, 25, "%d", total_vh);
	context->setValue(context->ctx,"list_vh", s.str().c_str());			
	context->setValue(context->ctx,"total_vh", total_vh_s);			

	tinydir_close(&dir);
	return WHM_OK;

bail:
	tinydir_close(&dir);
	context->setError(context->ctx,"path not exists");
	return WHM_OK;
}

bool isValidIP(string ip){
	string delim=".";
	string ret[4];

	string::size_type loc=0,start =0;
	for(int i=0;i<4;i++){
		loc = ip.find(delim, start);
		if(loc != string::npos){
			ret[i]=ip.substr(start,loc-start);
			start=loc+1;
		}else if(i==3){
			ret[i]=ip.substr(start);
		}else{
			//格式不对，应该有3个.
			return false;
		}
	}
	for(int i=0;i<4;i++){
		int num=atoi(ret[i].c_str());
		if(num>255){
			return false;
		}else if((num==0)&&(ret[i].compare("0"))){
			return false;
		}
	}

	return true;
}
//配置独立ssl
int ssl_vh(WHM_CONTEXT *context)
{
	char path[256];
	char file[256];
	char sharefile[256];
	char vh[256];
	char delims[] = ",";
	char *ip;
	int i=0;
	std::vector<char*> vChar;
	string s;
	const char *kangle_home = context->getEnv(context->ctx,"kangle_home");

	const char *domain = context->getUrl(context->ctx,"domain");
	const char *bind_ip = context->getUrl(context->ctx,"bind_ip");
	
	snprintf(path,256, "%s/vhetc/", kangle_home);
	snprintf(sharefile,256, "%s/etc/sslbind.xml", kangle_home);
	snprintf(file, 256, "%s/%s.xml", path, domain);
	snprintf(vh, 256, "%s/etc/vh.d/%s.xml", kangle_home, domain);

	if(domain==NULL || bind_ip==NULL){
		context->setError(context->ctx,"domain,bind_ip param is missing");
		return WHM_PARAM_ERROR;
	}

     fstream _file;
     _file.open(vh, ios::in);
     if(!_file)	{
		context->setError(context->ctx,"domain not exist");
		return WHM_CALL_FAILED;     
     }
	
	ip = strtok(const_cast<char*>(bind_ip), delims);
	while(ip != NULL) {
		if(isValidIP(ip)) {
			vChar.push_back(ip);
			s.append("<bind>!").append(ip).append(":443s</bind>\n");
		}
		ip = strtok( NULL, delims );
	}
	ofstream  sout(file);
	sout << s.c_str();	
	s.clear();

	ip = strtok(const_cast<char*>(bind_ip), delims);
	while(ip != NULL) {
		if(isValidIP(ip)) s.append("<bind>!").append(ip).append(":443s</bind>\n");
		ip = strtok( NULL, delims );
	}
	ofstream  fout(file);
	fout << s.c_str();
	vChar.clear();
	return WHM_OK;
}

DLL_PUBLIC BOOL WINAPI GetWhmVersion(WHM_VERSION_INFO *pVer)
{
	
	return TRUE;
}
DLL_PUBLIC int WINAPI WhmCall(const char *callName, const char *eventType,WHM_CONTEXT *context)
{
	if(strcasecmp(callName,"test_vhmd5")==0){
		return WHM_OK;
	}


	if(strcasecmp(callName,"list_vh")==0){
		return list_vh(context);
	}

	//vhsmd5.whm?whm_call=ssl_vh&domain=test.com&ip=1.1.1.1&other=2.2.2.2,3.3.3.3,4.4.4.4
	if(strcasecmp(callName,"ssl_vh")==0){
		return ssl_vh(context);
	}
		
	return WHM_COMMAND_FAILED;
}
DLL_PUBLIC BOOL WINAPI WhmTerminate(DWORD dwFlags)
{
	return TRUE;
}
